Repository Public
1import type { Metadata } from "next";2import Link from "next/link";3import { BenchmarkChart } from "@/components/charts/BenchmarkChart";4import { Arrow, PageIntro } from "@/components/ui/Section";5import { nodeById, publishedBenchmarks } from "@/lib/data";6import { formatDate, getDict, type Locale } from "@/lib/i18n";7import { pageMetadata } from "@/lib/seo";89type Props = { params: Promise<{ locale: Locale }> };1011export async function generateMetadata({ params }: Props): Promise<Metadata> {12 return pageMetadata((await params).locale, "benchmarks", "/benchmarks");13}1415export default async function BenchmarksPage({ params }: Props) {16 const { locale } = await params;17 const b = getDict(locale).benchmarks;18 const rows = publishedBenchmarks.map((o) => ({ ...o, nodeName: nodeById(o.nodeId)?.publicName ?? o.nodeId }));19 const metrics = [...new Set(rows.map((r) => r.metric))];20 return (21 <>22 <PageIntro eyebrow={b.eyebrow} title={b.title} intro={b.intro} />23 <div className="shell">24 {rows.length === 0 ? (25 <section aria-labelledby="forth-h" className="reveal relative overflow-hidden rounded-2xl border border-dashed border-line-strong bg-surface p-6 md:p-12" data-testid="benchmarks-empty">26 <p className="eyebrow">{b.forthcoming.label}</p>27 <h2 id="forth-h" className="h2 mt-5 max-w-[24ch]">{b.forthcoming.title}</h2>28 <p className="prose-tech mt-5">{b.forthcoming.body}</p>29 <h3 className="label mt-10">{b.plannedTitle}</h3>30 <ul className="mt-4 grid gap-x-10 gap-y-2.5 text-[0.9375rem] text-body sm:grid-cols-2">31 {b.plannedItems.map((p) => <li key={p} className="flex gap-3"><span aria-hidden="true" className="mt-[0.7em] h-px w-3 shrink-0 bg-accent" />{p}</li>)}32 </ul>33 </section>34 ) : (35 <section aria-labelledby="res-h" data-testid="benchmarks-results">36 <h2 id="res-h" className="h2">{b.resultsTitle}</h2>37 {metrics.map((m) => {38 const group = rows.filter((r) => r.metric === m);39 return (40 <div key={m} className="mt-10 border-t border-line pt-8">41 <h3 className="label">{m}</h3>42 <div className="mt-4 max-w-3xl"><BenchmarkChart rows={group} label={m} alt={b.chartAlt(m)} /></div>43 <div className="mt-6 overflow-x-auto" tabIndex={0} role="region" aria-label={m}>44 <table className="num w-full min-w-[46rem] text-left text-[0.875rem]">45 <thead className="border-b border-line"><tr>{Object.values(b.table).map((h) => <th key={h} scope="col" className="label px-3 py-2 font-normal">{h}</th>)}</tr></thead>46 <tbody>47 {group.map((r) => (48 <tr key={r.id} className="border-b border-line">49 <th scope="row" className="px-3 py-2 font-medium"><Link className="link" href={`/${locale}/nodes/${r.nodeId}`}>{r.nodeName}</Link></th>50 <td className="px-3 py-2">{r.modelId} {r.modelVersion}</td>51 <td className="px-3 py-2">{r.quantization}</td>52 <td className="px-3 py-2">{r.runtime} {r.runtimeVersion}</td>53 <td className="px-3 py-2 font-mono">{r.value} ± {r.uncertainty}</td>54 <td className="px-3 py-2 font-mono">{r.repetitions}</td>55 <td className="px-3 py-2">{formatDate(r.measuredAt, locale)}</td>56 </tr>57 ))}58 </tbody>59 </table>60 </div>61 </div>62 );63 })}64 </section>65 )}6667 <section aria-labelledby="proto-h" className="grid gap-8 pt-20 md:grid-cols-12 md:pt-28">68 <div className="md:col-span-4">69 <h2 id="proto-h" className="h2">{b.protocolTitle}</h2>70 <p className="prose-tech mt-5">{b.protocolIntro}</p>71 </div>72 <dl className="divide-y divide-line border-y border-line md:col-span-8">73 {b.fields.map((f, i) => (74 <div key={f.k} className="reveal grid gap-2 py-4 sm:grid-cols-[3rem_11rem_1fr] sm:gap-5">75 <span aria-hidden="true" className="num font-mono text-[0.6875rem] text-accent">{String(i + 1).padStart(2, "0")}</span>76 <dt className="font-medium">{f.k}</dt>77 <dd className="text-[0.9375rem] leading-relaxed text-body">{f.v}</dd>78 </div>79 ))}80 </dl>81 </section>8283 <section aria-labelledby="limits-h" className="grid gap-8 pt-20 md:grid-cols-12 md:pt-28">84 <div className="md:col-span-4"><h2 id="limits-h" className="h2">{b.limitsTitle}</h2></div>85 <ol className="space-y-5 md:col-span-8">86 {b.limits.map((l, i) => (87 <li key={l.slice(0, 24)} className="reveal flex gap-5 border-t border-line pt-5">88 <span aria-hidden="true" className="num font-mono text-[0.6875rem] text-mute">{String(i + 1).padStart(2, "0")}</span>89 <p className="text-[1rem] leading-relaxed text-body">{l}</p>90 </li>91 ))}92 </ol>93 </section>9495 <section aria-labelledby="else-h" className="card mt-20 p-7 md:mt-28 md:p-10">96 <h2 id="else-h" className="text-xl font-medium tracking-[-0.02em]">{b.elsewhere.title}</h2>97 <p className="prose-tech mt-4">{b.elsewhere.body}</p>98 <p className="mt-6"><Link className="link inline-flex items-center gap-2" href={`/${locale}/research`}>{b.elsewhere.link} <Arrow /></Link></p>99 </section>100 </div>101 </>102 );103}104